package com.basis.message;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.openbravo.base.model.Entity;
import org.openbravo.base.model.ModelProvider;
import org.openbravo.base.structure.BaseOBObject;
import org.openbravo.dal.service.OBDal;

@SuppressWarnings("unchecked")
public class SendAlertMessageUtil {
	private static Logger logger = Logger.getLogger(SendAlertMessageUtil.class);
	private static Map<String, MessageObj> msgObjMap = null;
	private static Map<String, Map<String, List<String>>> entityCodeMap = null;
	private static Entity[] entities = null;
	
	/**
	 * 通过消息编码，传入消息头、消息内容发送消息
	 * @param msgCode
	 * @param title
	 * @param text
	 */
	public static void sendMessageText(String msgCode, String title, String text) {
		String sql = "{call Mes_Message.send(?, ?, ?)}";
		
		Query query = OBDal.getInstance().getSession().createSQLQuery(sql);
		query.setString(0, msgCode);
		query.setString(1, title);
		query.setString(2, text);
		query.executeUpdate();
	}
	
	/**
	 * 通过消息编码，传入消息头、消息内容发送消息
	 * @param msgCode
	 * @param title
	 * @param text
	 */
	public static void sendMessageText(String msgCode, String title, String text, String userId) {
		String sql = "{call Mes_Message.send(?, ?, ?, '', ?)}";
		Query query = OBDal.getInstance().getSession().createSQLQuery(sql);
		query.setString(0, msgCode);
		query.setString(1, title);
		query.setString(2, text);
		query.setString(3, userId);
		query.executeUpdate();
	}
	
	/**
	 * 通过消息编码发送消息提醒
	 * @param msgCode
	 */
	public static void sendMessage(String msgCode) {
		String sql = "{call Mes_Message.send(?)}";
		Query query = OBDal.getInstance().getSession().createSQLQuery(sql);
		query.setString(0, msgCode);
		query.executeUpdate();
	}
	/**
	 * 通过消息编码发送消息提醒
	 * @param msgCode
	 */
	public static void sendMessage(String msgCode, String userId) {
		String sql = "{call Mes_Message.send(?, '', '', '', ?)}";
		Query query = OBDal.getInstance().getSession().createSQLQuery(sql);
		query.setString(0, msgCode);
		query.setString(1, userId);
		query.executeUpdate();
	}

	/**
	 * 通过实体类名，操作方式发送消息提醒
	 * @param entityClassName
	 * @param operateType
	 */
	public static void sendMessage(BaseOBObject baseObj, String operateType) {
		try {
			initEntities();
			Map<String, List<String>> map = entityCodeMap.get(baseObj.getClass().getName());
			if (map != null) {
				List<String> list = map.get(operateType);
				if (list != null && !list.isEmpty()) {
					//判断条件
					for (String code : list) {
						if (caseResutl(code, baseObj)) {
							sendMessage(code);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("实体操作触发消息提醒异常：" + e.getMessage(), e);
		}
	}
	
	//根据
	private static boolean caseResutl(String code, BaseOBObject baseObj) throws Exception {
		MessageObj obj = msgObjMap.get(code);
		String where = obj.getFilterClause();
		if (where != null) {
			return FilterResultUtil.check(where, baseObj);
		} else {
			//未设置过滤条件时直接发送消息
			return true;
		}
	}

	//获取所有消息提醒实体对象
	public static synchronized Entity[] getEntities() {
		initEntities();
		if (entities == null) {
			entities = new Entity[msgObjMap.keySet().size()];
			int i = 0;
			Class clzz = null;
			for (String code : msgObjMap.keySet()) {
				try {
					clzz = Class.forName(msgObjMap.get(code).getEntityClassName());
					entities[i] = ModelProvider.getInstance().getEntity(clzz);
					i ++;
				} catch (Exception e) {
					System.out.println("消息提醒对象：【" + code + "】未找到实体类\"" + msgObjMap.get(code).getEntityClassName() + "\"");
				}
			}
		}
		return entities;
	}
	
	/**
	 * 初始化消息提醒内容信息
	**/
	private static void initEntities() {
		if (msgObjMap == null) {
			String sql = "select code, Entity_Class, Opr_Type, filter_clause from Emes_Message_Obj " +
					"where Entity_Class is not null and Type = '1'";
			Query query = OBDal.getInstance().getSession().createSQLQuery(sql);
			List<Object[]> list = query.list();
			
			msgObjMap = new HashMap<String, MessageObj>();
			entityCodeMap = new HashMap<String, Map<String, List<String>>>();
			Map<String, List<String>> map = null;
			List<String> codeList = null;
			
			MessageObj msg = null;
			for (Object[] obj : list) {
				msg = new MessageObj();
				msg.setCode((String)obj[0]);
				msg.setEntityClassName((String)obj[1]);
				msg.setOperateType((String)obj[2]);//add/update/delete
				msg.setFilterClause((String)obj[3]);
				
				//将实体类名与消息检验关系
				msgObjMap.put(msg.getCode(), msg);
				map = entityCodeMap.get(msg.getEntityClassName());
				if (map == null) {
					map = new HashMap<String, List<String>>();
					entityCodeMap.put(msg.getEntityClassName(), map);
				}
				codeList = map.get(msg.getOperateType());
				if (codeList == null) {
					codeList = new ArrayList<String>();
					map.put(msg.getOperateType(), codeList);
				}
				codeList.add(msg.getCode());
			}
		}
	}
	
	/**
	 * 重新加载数据库消息配置信息
	 */
	public static void reloadEntities() {
		msgObjMap = null;
		entityCodeMap = null;
		entities = null;
	}

	static class MessageObj {
		private String code;//消息对象编码
		private String entityClassName;//消息对象实体类
		private String operateType;//消息对象操作类型
		private String filterClause;//过滤条件
		
		public String getCode() {
			return code;
		}
		public void setCode(String code) {
			this.code = code;
		}
		public String getEntityClassName() {
			return entityClassName;
		}
		public void setEntityClassName(String entityClassName) {
			this.entityClassName = entityClassName;
		}
		public String getOperateType() {
			return operateType;
		}
		public void setOperateType(String operateType) {
			this.operateType = operateType;
		}
		public String getFilterClause() {
			return filterClause;
		}
		public void setFilterClause(String filterClause) {
			this.filterClause = filterClause;
		}
	}
}
